import { Callout } from 'nextra/components';
import { Tabs } from 'nextra/components';
import { Steps } from 'nextra/components';
import { Widget } from '@/components/demo/widget.tsx';
import LinkBadge from '@/components/ui/link-badge/link-badge.tsx';
import LinkBadgeGroup from '@/components/ui/link-badge/link-badge-group.tsx';

# Sidebar

A sidebar widget that provides an opinionated layout for navigation on the side of the screen.

<LinkBadgeGroup>
    <LinkBadge label="API Reference" href="https://pub.dev/documentation/forui/latest/forui.widgets.sidebar/"/>
</LinkBadgeGroup>

<Callout type="info">
    A sidebar is typically used with `FScaffold`. Usage of `FScaffold` can be found [here](/docs/layout/scaffold).
</Callout>

<Tabs items={['Preview', 'Code']}>
    <Tabs.Tab>
        <Widget name='sidebar' variant='default' height={500}/>
    </Tabs.Tab>
    <Tabs.Tab>
      ```dart copy
      FScaffold(
        sidebar: FSidebar(
          header: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Padding(
                  padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
                  child: SvgPicture.network(
                    theme.colors.brightness == Brightness.light
                        ? 'https://forui.dev/light_logo.svg'
                        : 'https://forui.dev/dark_logo.svg',
                    height: 24,
                    colorFilter: ColorFilter.mode(context.theme.colors.foreground, BlendMode.srcIn),
                  ),
                ),
                FDivider(style: context.theme.dividerStyles.horizontalStyle.copyWith(padding: EdgeInsets.zero)),
              ],
            ),
          ),
          footer: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: FCard.raw(
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
                child: Row(
                  spacing: 10,
                  children: [
                    FAvatar.raw(child: Icon(FIcons.userRound, size: 18, color: context.theme.colors.mutedForeground)),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        spacing: 2,
                        children: [
                          Text(
                            'Dash',
                            style: context.theme.typography.sm.copyWith(
                              fontWeight: FontWeight.bold,
                              color: context.theme.colors.foreground,
                            ),
                            overflow: TextOverflow.ellipsis,
                          ),
                          Text(
                            'dash@forui.dev',
                            style: context.theme.typography.xs.copyWith(color: context.theme.colors.mutedForeground),
                            overflow: TextOverflow.ellipsis,
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
          children: [
            FSidebarGroup(
              label: const Text('Overview'),
              children: [
                FSidebarItem(
                  icon: const Icon(FIcons.school),
                  label: const Text('Getting Started'),
                  initiallyExpanded: true,
                  onPress: () {},
                  children: [
                    FSidebarItem(label: const Text('Installation'), selected: true, onPress: () {}),
                    FSidebarItem(label: const Text('Themes'), onPress: () {}),
                    FSidebarItem(label: const Text('Typography'), onPress: () {}),
                  ],
                ),
                FSidebarItem(icon: const Icon(FIcons.code), label: const Text('API Reference'), onPress: () {}),
                FSidebarItem(icon: const Icon(FIcons.box), label: const Text('Pub Dev'), onPress: () {}),
              ],
            ),
            FSidebarGroup(
              action: const Icon(FIcons.plus),
              onActionPress: () {},
              label: const Text('Widgets'),
              children: [
                FSidebarItem(icon: const Icon(FIcons.circleSlash), label: const Text('Divider'), onPress: () {}),
                FSidebarItem(icon: const Icon(FIcons.scaling), label: const Text('Resizable'), onPress: () {}),
                FSidebarItem(icon: const Icon(FIcons.layoutDashboard), label: const Text('Scaffold'), onPress: () {}),
              ],
            ),
          ],
        ),
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 14),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            spacing: 12,
            children: [
              FBreadcrumb(
                children: [
                  FBreadcrumbItem(onPress: () {}, child: const Text('Forui')),
                  FBreadcrumbItem.collapsed(
                    menu: [
                      FItemGroup(
                        children: [
                          FItem(title: const Text('Documentation'), onPress: () {}),
                          FFItemTile(title: const Text('Themes'), onPress: () {}),
                        ],
                      ),
                    ],
                  ),
                  FBreadcrumbItem(onPress: () {}, child: const Text('Overview')),
                  const FBreadcrumbItem(current: true, child: Text('Installation')),
                ],
              ),
              Expanded(
                child: Container(
                  decoration: BoxDecoration(
                    color: context.theme.colors.muted,
                    borderRadius: context.theme.style.borderRadius,
                  ),
                ),
              ),
              Expanded(
                flex: 3,
                child: Container(
                  decoration: BoxDecoration(
                    color: context.theme.colors.muted,
                    borderRadius: context.theme.style.borderRadius,
                  ),
                ),
              ),
            ],
          ),
        ),
      );
      ```
    </Tabs.Tab>
</Tabs>

## CLI

To generate and customize this style:

```shell copy
dart run forui style create sidebar
```

## Anatomy

This segment describes the anatomy of the various elements of a sidebar.

### `FSidebar`

The widget that provides an opinionated layout on the side of the screen. The widget has the following sections:

| Name    | Parameter      | Position   | Optional |
| :------ | :------------- | :--------- | :------- |
| header  | header         | sticky     | ✅       |
| content | child/children | scrollable | ❌       |
| footer  | footer         | sticky     | ✅       |

### `FSidebarGroup`

A widget that is used to group several `FSidebarItem`s.

### `FSidebarItem`

Represents an item on the sidebar. May be nested in `FSidebarItem.children` to create nested items.

## Usage

### `FSidebar(...)`

```dart copy
FSidebar(
  style: FSidebarStyle(...),
  header: const Text('Header'),
  footer: const Text('Footer'),
  children: [FSidebarGroup(...)],
);
```

### `FSidebar.builder(...)`

```dart copy
FSidebar.builder(
  style: FSidebarStyle(...),
  header: const Text('Header'),
  footer: const Text('Footer'),
  itemCount: 5,
  itemBuilder: (context, index) => FSidebarGroup(...),
);
```

### `FSidebar.raw(...)`

```dart copy
FSidebar.raw(
  style: FSidebarStyle(...),
  header: const Text('Header'),
  footer: const Text('Footer'),
  child: SizedBox(),
);
```

### `FSidebarGroup(...)`

```dart copy
FSidebarGroup(
  style: FSidebarGroupStyle(...),
  label: const Text('Group'),
  action: const Icon(FIcons.plus),
  onActionPress: () {},
  children: [FSidebarItem(...)],
);
```

### `FSidebarItem(...)`

```dart copy
FSidebarItem(
  style: FSidebarItemStyle(...),
  icon: const Icon(FIcons.box),
  label: const Text('Item'),
  selected: false,
  initiallyExpanded: false,
  onPress: () {},
  onLongPress: () {},
  onHoverChange: (hovered) {},
  onStateChange: (delta) {},
  children: [FSidebarItem(...)],
);
```

## Examples

### Sheet Sidebar

Suited for devices with limited screen space.

<Tabs items={['Preview', 'Code']}>
    <Tabs.Tab>
        <Widget name='sidebar' variant='sheet' height={500} />
    </Tabs.Tab>
    <Tabs.Tab>
        ```dart copy
        Widget _sidebar(BuildContext context) => DecoratedBox(
          decoration: BoxDecoration(color: context.theme.colors.background),
          child: FSidebar(
            style: (s) => s.copyWith(constraints: s.constraints.copyWith(minWidth: 300, maxWidth: 300)),
            header: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Padding(
                    padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
                    child: SvgPicture.network(
                      theme.colors.brightness == Brightness.light
                          ? 'https://forui.dev/light_logo.svg'
                          : 'https://forui.dev/dark_logo.svg',
                      height: 24,
                      colorFilter: ColorFilter.mode(context.theme.colors.foreground, BlendMode.srcIn),
                    ),
                  ),
                  FDivider(style: context.theme.dividerStyles.horizontalStyle.copyWith(padding: EdgeInsets.zero)),
                ],
              ),
            ),
            footer: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: FCard.raw(
                child: Padding(
                  padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
                  child: Row(
                    spacing: 10,
                    children: [
                      FAvatar.raw(child: Icon(FIcons.userRound, size: 18, color: context.theme.colors.mutedForeground)),
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          spacing: 2,
                          children: [
                            Text(
                              'Dash',
                              style: context.theme.typography.sm.copyWith(
                                fontWeight: FontWeight.bold,
                                color: context.theme.colors.foreground,
                              ),
                              overflow: TextOverflow.ellipsis,
                            ),
                            Text(
                              'dash@forui.dev',
                              style: context.theme.typography.xs.copyWith(color: context.theme.colors.mutedForeground),
                              overflow: TextOverflow.ellipsis,
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
            children: [
              FSidebarGroup(
                label: const Text('Overview'),
                children: [
                  FSidebarItem(
                    icon: const Icon(FIcons.school),
                    label: const Text('Getting Started'),
                    initiallyExpanded: true,
                    onPress: () {},
                    children: [
                      FSidebarItem(label: const Text('Installation'), selected: true, onPress: () {}),
                      FSidebarItem(label: const Text('Themes'), onPress: () {}),
                      FSidebarItem(label: const Text('Typography'), onPress: () {}),
                    ],
                  ),
                  FSidebarItem(icon: const Icon(FIcons.code), label: const Text('API Reference'), onPress: () {}),
                  FSidebarItem(icon: const Icon(FIcons.box), label: const Text('Pub Dev'), onPress: () {}),
                ],
              ),
              FSidebarGroup(
                action: const Icon(FIcons.plus),
                onActionPress: () {},
                label: const Text('Widgets'),
                children: [
                  FSidebarItem(icon: const Icon(FIcons.circleSlash), label: const Text('Divider'), onPress: () {}),
                  FSidebarItem(icon: const Icon(FIcons.scaling), label: const Text('Resizable'), onPress: () {}),
                  FSidebarItem(icon: const Icon(FIcons.layoutDashboard), label: const Text('Scaffold'), onPress: () {}),
                ],
              ),
            ],
          ),
        );

        @override
        Widget build(BuildContext context) => Center(
          child: FButton(
            child: const Text('Open Sidebar'),
            onPress: () => showFSheet(context: context, side: FLayout.ltr, builder: _sidebar),
          ),
        );
        ```
    </Tabs.Tab>

</Tabs>

### Custom Width

<Tabs items={['Preview', 'Code']}>
    <Tabs.Tab>
        <Widget name='sidebar' variant='custom-width' height={300} />
    </Tabs.Tab>
    <Tabs.Tab>
        ```dart {2} copy
        FSidebar(
          style: (s) => s.copyWith(constraints: s.constraints.copyWith(minWidth: 500, maxWidth: 500)),
          children: [
            FSidebarGroup(
              children: [
                FSidebarItem(
                  icon: const Icon(FIcons.layoutDashboard),
                  label: const Text('Dashboard'),
                  selected: true,
                  onPress: () {},
                ),
                FSidebarItem(icon: const Icon(FIcons.chartLine), label: const Text('Analytics'), onPress: () {}),
                FSidebarItem(
                  icon: const Icon(FIcons.chartBar),
                  label: const Text('Reports'),
                  initiallyExpanded: true,
                  children: [
                    FSidebarItem(label: const Text('Daily'), onPress: () {}),
                    FSidebarItem(label: const Text('Weekly'), onPress: () {}),
                    FSidebarItem(label: const Text('Monthly'), onPress: () {}),
                  ],
                ),
              ],
            ),
          ],
        );
        ```
    </Tabs.Tab>
</Tabs>

### Nested `FSidebarItem`

<Tabs items={['Preview', 'Code']}>
    <Tabs.Tab>
        <Widget name='sidebar' variant='nested' height={500} />
    </Tabs.Tab>
    <Tabs.Tab>
        ```dart copy
        FSidebar(
        style: (s) => s.copyWith(constraints: s.constraints.copyWith(minWidth: 300, maxWidth: 300)),
        children: [
          FSidebarGroup(
            children: [
              FSidebarItem(
                icon: const Icon(FIcons.userRound),
                label: const Text('Account'),
                initiallyExpanded: true,
                children: [
                  FSidebarItem(
                    label: const Text('Profile'),
                    children: [
                      FSidebarItem(label: const Text('Personal Info'), onPress: () {}),
                      FSidebarItem(label: const Text('Preferences'), onPress: () {}),
                    ],
                  ),
                  FSidebarItem(
                    label: const Text('Security'),
                    initiallyExpanded: true,
                    children: [
                      FSidebarItem(
                        label: const Text('Password'),
                        initiallyExpanded: true,
                        children: [
                          FSidebarItem(label: const Text('Change Password'), onPress: () {}),
                          FSidebarItem(label: const Text('Password History'), onPress: () {}),
                        ],
                      ),
                      FSidebarItem(label: const Text('Two-Factor Authentication'), onPress: () {}),
                      FSidebarItem(label: const Text('Device History'), onPress: () {}),
                    ],
                  ),
                  FSidebarItem(label: const Text('Notifications'), onPress: () {}),
                ],
              ),
              FSidebarItem(icon: const Icon(FIcons.palette), label: const Text('Appearance'), onPress: () {}),
              FSidebarItem(icon: const Icon(FIcons.settings), label: const Text('System'), onPress: () {}),
            ],
          ),
        ],
      );
        ```
    </Tabs.Tab>
</Tabs>
